1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 package javax.swing.tree;
27
28 import java.beans.PropertyChangeListener;
29 import java.io.*;
30 import java.util.ArrayList;
31 import java.util.BitSet;
32 import java.util.Enumeration;
33 import java.util.EventListener;
34 import java.util.Hashtable;
35 import java.util.List;
36 import java.util.Vector;
37 import javax.swing.event.*;
38 import javax.swing.DefaultListSelectionModel;
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64 public class DefaultTreeSelectionModel implements Cloneable, Serializable, TreeSelectionModel
65 {
66
67 public static final String SELECTION_MODE_PROPERTY = "selectionMode";
68
69
70 protected SwingPropertyChangeSupport changeSupport;
71
72
73
74 protected TreePath[] selection;
75
76
77 protected EventListenerList listenerList = new EventListenerList();
78
79
80 transient protected RowMapper rowMapper;
81
82
83
84 protected DefaultListSelectionModel listSelectionModel;
85
86
87
88
89 protected int selectionMode;
90
91
92 protected TreePath leadPath;
93
94 protected int leadIndex;
95
96 protected int leadRow;
97
98
99
100
101 private Hashtable<TreePath, Boolean> uniquePaths;
102 private Hashtable<TreePath, Boolean> lastPaths;
103 private TreePath[] tempPaths;
104
105
106
107
108
109
110 public DefaultTreeSelectionModel() {
111 listSelectionModel = new DefaultListSelectionModel();
112 selectionMode = DISCONTIGUOUS_TREE_SELECTION;
113 leadIndex = leadRow = -1;
114 uniquePaths = new Hashtable<TreePath, Boolean>();
115 lastPaths = new Hashtable<TreePath, Boolean>();
116 tempPaths = new TreePath[1];
117 }
118
119
120
121
122
123 public void setRowMapper(RowMapper newMapper) {
124 rowMapper = newMapper;
125 resetRowSelection();
126 }
127
128
129
130
131
132 public RowMapper getRowMapper() {
133 return rowMapper;
134 }
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150 public void setSelectionMode(int mode) {
151 int oldMode = selectionMode;
152
153 selectionMode = mode;
154 if(selectionMode != TreeSelectionModel.SINGLE_TREE_SELECTION &&
155 selectionMode != TreeSelectionModel.CONTIGUOUS_TREE_SELECTION &&
156 selectionMode != TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION)
157 selectionMode = TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION;
158 if(oldMode != selectionMode && changeSupport != null)
159 changeSupport.firePropertyChange(SELECTION_MODE_PROPERTY,
160 Integer.valueOf(oldMode),
161 Integer.valueOf(selectionMode));
162 }
163
164
165
166
167
168
169 public int getSelectionMode() {
170 return selectionMode;
171 }
172
173
174
175
176
177
178
179
180 public void setSelectionPath(TreePath path) {
181 if(path == null)
182 setSelectionPaths(null);
183 else {
184 TreePath[] newPaths = new TreePath[1];
185
186 newPaths[0] = path;
187 setSelectionPaths(newPaths);
188 }
189 }
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214 public void setSelectionPaths(TreePath[] pPaths) {
215 int newCount, newCounter, oldCount, oldCounter;
216 TreePath[] paths = pPaths;
217
218 if(paths == null)
219 newCount = 0;
220 else
221 newCount = paths.length;
222 if(selection == null)
223 oldCount = 0;
224 else
225 oldCount = selection.length;
226 if((newCount + oldCount) != 0) {
227 if(selectionMode == TreeSelectionModel.SINGLE_TREE_SELECTION) {
228
229
230 if(newCount > 1) {
231 paths = new TreePath[1];
232 paths[0] = pPaths[0];
233 newCount = 1;
234 }
235 }
236 else if(selectionMode ==
237 TreeSelectionModel.CONTIGUOUS_TREE_SELECTION) {
238
239
240 if(newCount > 0 && !arePathsContiguous(paths)) {
241 paths = new TreePath[1];
242 paths[0] = pPaths[0];
243 newCount = 1;
244 }
245 }
246
247 TreePath beginLeadPath = leadPath;
248 Vector<PathPlaceHolder> cPaths = new Vector<PathPlaceHolder>(newCount + oldCount);
249 List<TreePath> newSelectionAsList =
250 new ArrayList<TreePath>(newCount);
251
252 lastPaths.clear();
253 leadPath = null;
254
255 for(newCounter = 0; newCounter < newCount; newCounter++) {
256 TreePath path = paths[newCounter];
257 if (path != null && lastPaths.get(path) == null) {
258 lastPaths.put(path, Boolean.TRUE);
259 if (uniquePaths.get(path) == null) {
260 cPaths.addElement(new PathPlaceHolder(path, true));
261 }
262 leadPath = path;
263 newSelectionAsList.add(path);
264 }
265 }
266
267 TreePath[] newSelection = newSelectionAsList.toArray(
268 new TreePath[newSelectionAsList.size()]);
269
270
271 for(oldCounter = 0; oldCounter < oldCount; oldCounter++)
272 if(selection[oldCounter] != null &&
273 lastPaths.get(selection[oldCounter]) == null)
274 cPaths.addElement(new PathPlaceHolder
275 (selection[oldCounter], false));
276
277 selection = newSelection;
278
279 Hashtable<TreePath, Boolean> tempHT = uniquePaths;
280
281 uniquePaths = lastPaths;
282 lastPaths = tempHT;
283 lastPaths.clear();
284
285
286 insureUniqueness();
287
288 updateLeadIndex();
289
290 resetRowSelection();
291
292 if(cPaths.size() > 0)
293 notifyPathChange(cPaths, beginLeadPath);
294 }
295 }
296
297
298
299
300
301
302
303
304 public void addSelectionPath(TreePath path) {
305 if(path != null) {
306 TreePath[] toAdd = new TreePath[1];
307
308 toAdd[0] = path;
309 addSelectionPaths(toAdd);
310 }
311 }
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328 public void addSelectionPaths(TreePath[] paths) {
329 int newPathLength = ((paths == null) ? 0 : paths.length);
330
331 if(newPathLength > 0) {
332 if(selectionMode == TreeSelectionModel.SINGLE_TREE_SELECTION) {
333 setSelectionPaths(paths);
334 }
335 else if(selectionMode == TreeSelectionModel.
336 CONTIGUOUS_TREE_SELECTION && !canPathsBeAdded(paths)) {
337 if(arePathsContiguous(paths)) {
338 setSelectionPaths(paths);
339 }
340 else {
341 TreePath[] newPaths = new TreePath[1];
342
343 newPaths[0] = paths[0];
344 setSelectionPaths(newPaths);
345 }
346 }
347 else {
348 int counter, validCount;
349 int oldCount;
350 TreePath beginLeadPath = leadPath;
351 Vector<PathPlaceHolder> cPaths = null;
352
353 if(selection == null)
354 oldCount = 0;
355 else
356 oldCount = selection.length;
357
358
359 lastPaths.clear();
360 for(counter = 0, validCount = 0; counter < newPathLength;
361 counter++) {
362 if(paths[counter] != null) {
363 if (uniquePaths.get(paths[counter]) == null) {
364 validCount++;
365 if(cPaths == null)
366 cPaths = new Vector<PathPlaceHolder>();
367 cPaths.addElement(new PathPlaceHolder
368 (paths[counter], true));
369 uniquePaths.put(paths[counter], Boolean.TRUE);
370 lastPaths.put(paths[counter], Boolean.TRUE);
371 }
372 leadPath = paths[counter];
373 }
374 }
375
376 if(leadPath == null) {
377 leadPath = beginLeadPath;
378 }
379
380 if(validCount > 0) {
381 TreePath newSelection[] = new TreePath[oldCount +
382 validCount];
383
384
385 if(oldCount > 0)
386 System.arraycopy(selection, 0, newSelection, 0,
387 oldCount);
388 if(validCount != paths.length) {
389
390
391 Enumeration<TreePath> newPaths = lastPaths.keys();
392
393 counter = oldCount;
394 while (newPaths.hasMoreElements()) {
395 newSelection[counter++] = newPaths.nextElement();
396 }
397 }
398 else {
399 System.arraycopy(paths, 0, newSelection, oldCount,
400 validCount);
401 }
402
403 selection = newSelection;
404
405 insureUniqueness();
406
407 updateLeadIndex();
408
409 resetRowSelection();
410
411 notifyPathChange(cPaths, beginLeadPath);
412 }
413 else
414 leadPath = beginLeadPath;
415 lastPaths.clear();
416 }
417 }
418 }
419
420
421
422
423
424
425
426
427 public void removeSelectionPath(TreePath path) {
428 if(path != null) {
429 TreePath[] rPath = new TreePath[1];
430
431 rPath[0] = path;
432 removeSelectionPaths(rPath);
433 }
434 }
435
436
437
438
439
440
441
442
443 public void removeSelectionPaths(TreePath[] paths) {
444 if (paths != null && selection != null && paths.length > 0) {
445 if(!canPathsBeRemoved(paths)) {
446
447 clearSelection();
448 }
449 else {
450 Vector<PathPlaceHolder> pathsToRemove = null;
451
452
453 for (int removeCounter = paths.length - 1; removeCounter >= 0;
454 removeCounter--) {
455 if(paths[removeCounter] != null) {
456 if (uniquePaths.get(paths[removeCounter]) != null) {
457 if(pathsToRemove == null)
458 pathsToRemove = new Vector<PathPlaceHolder>(paths.length);
459 uniquePaths.remove(paths[removeCounter]);
460 pathsToRemove.addElement(new PathPlaceHolder
461 (paths[removeCounter], false));
462 }
463 }
464 }
465 if(pathsToRemove != null) {
466 int removeCount = pathsToRemove.size();
467 TreePath beginLeadPath = leadPath;
468
469 if(removeCount == selection.length) {
470 selection = null;
471 }
472 else {
473 Enumeration<TreePath> pEnum = uniquePaths.keys();
474 int validCount = 0;
475
476 selection = new TreePath[selection.length -
477 removeCount];
478 while (pEnum.hasMoreElements()) {
479 selection[validCount++] = pEnum.nextElement();
480 }
481 }
482 if (leadPath != null &&
483 uniquePaths.get(leadPath) == null) {
484 if (selection != null) {
485 leadPath = selection[selection.length - 1];
486 }
487 else {
488 leadPath = null;
489 }
490 }
491 else if (selection != null) {
492 leadPath = selection[selection.length - 1];
493 }
494 else {
495 leadPath = null;
496 }
497 updateLeadIndex();
498
499 resetRowSelection();
500
501 notifyPathChange(pathsToRemove, beginLeadPath);
502 }
503 }
504 }
505 }
506
507
508
509
510
511 public TreePath getSelectionPath() {
512 if (selection != null && selection.length > 0) {
513 return selection[0];
514 }
515 return null;
516 }
517
518
519
520
521
522
523 public TreePath[] getSelectionPaths() {
524 if(selection != null) {
525 int pathSize = selection.length;
526 TreePath[] result = new TreePath[pathSize];
527
528 System.arraycopy(selection, 0, result, 0, pathSize);
529 return result;
530 }
531 return new TreePath[0];
532 }
533
534
535
536
537 public int getSelectionCount() {
538 return (selection == null) ? 0 : selection.length;
539 }
540
541
542
543
544
545 public boolean isPathSelected(TreePath path) {
546 return (path != null) ? (uniquePaths.get(path) != null) : false;
547 }
548
549
550
551
552 public boolean isSelectionEmpty() {
553 return (selection == null || selection.length == 0);
554 }
555
556
557
558
559
560 public void clearSelection() {
561 if (selection != null && selection.length > 0) {
562 int selSize = selection.length;
563 boolean[] newness = new boolean[selSize];
564
565 for(int counter = 0; counter < selSize; counter++)
566 newness[counter] = false;
567
568 TreeSelectionEvent event = new TreeSelectionEvent
569 (this, selection, newness, leadPath, null);
570
571 leadPath = null;
572 leadIndex = leadRow = -1;
573 uniquePaths.clear();
574 selection = null;
575 resetRowSelection();
576 fireValueChanged(event);
577 }
578 }
579
580
581
582
583
584
585
586 public void addTreeSelectionListener(TreeSelectionListener x) {
587 listenerList.add(TreeSelectionListener.class, x);
588 }
589
590
591
592
593
594
595
596 public void removeTreeSelectionListener(TreeSelectionListener x) {
597 listenerList.remove(TreeSelectionListener.class, x);
598 }
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613 public TreeSelectionListener[] getTreeSelectionListeners() {
614 return listenerList.getListeners(TreeSelectionListener.class);
615 }
616
617
618
619
620
621
622
623 protected void fireValueChanged(TreeSelectionEvent e) {
624
625 Object[] listeners = listenerList.getListenerList();
626
627
628
629 for (int i = listeners.length-2; i>=0; i-=2) {
630 if (listeners[i]==TreeSelectionListener.class) {
631
632
633
634 ((TreeSelectionListener)listeners[i+1]).valueChanged(e);
635 }
636 }
637 }
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676 public <T extends EventListener> T[] getListeners(Class<T> listenerType) {
677 return listenerList.getListeners(listenerType);
678 }
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694 public int[] getSelectionRows() {
695
696
697 if (rowMapper != null && selection != null && selection.length > 0) {
698 int[] rows = rowMapper.getRowsForPaths(selection);
699
700 if (rows != null) {
701 int invisCount = 0;
702
703 for (int counter = rows.length - 1; counter >= 0; counter--) {
704 if (rows[counter] == -1) {
705 invisCount++;
706 }
707 }
708 if (invisCount > 0) {
709 if (invisCount == rows.length) {
710 rows = null;
711 }
712 else {
713 int[] tempRows = new int[rows.length - invisCount];
714
715 for (int counter = rows.length - 1, visCounter = 0;
716 counter >= 0; counter--) {
717 if (rows[counter] != -1) {
718 tempRows[visCounter++] = rows[counter];
719 }
720 }
721 rows = tempRows;
722 }
723 }
724 }
725 return rows;
726 }
727 return new int[0];
728 }
729
730
731
732
733
734
735 public int getMinSelectionRow() {
736 return listSelectionModel.getMinSelectionIndex();
737 }
738
739
740
741
742
743
744 public int getMaxSelectionRow() {
745 return listSelectionModel.getMaxSelectionIndex();
746 }
747
748
749
750
751 public boolean isRowSelected(int row) {
752 return listSelectionModel.isSelectedIndex(row);
753 }
754
755
756
757
758
759
760
761
762
763
764
765
766 public void resetRowSelection() {
767 listSelectionModel.clearSelection();
768 if(selection != null && rowMapper != null) {
769 int aRow;
770 int validCount = 0;
771 int[] rows = rowMapper.getRowsForPaths(selection);
772
773 for(int counter = 0, maxCounter = selection.length;
774 counter < maxCounter; counter++) {
775 aRow = rows[counter];
776 if(aRow != -1) {
777 listSelectionModel.addSelectionInterval(aRow, aRow);
778 }
779 }
780 if(leadIndex != -1 && rows != null) {
781 leadRow = rows[leadIndex];
782 }
783 else if (leadPath != null) {
784
785 tempPaths[0] = leadPath;
786 rows = rowMapper.getRowsForPaths(tempPaths);
787 leadRow = (rows != null) ? rows[0] : -1;
788 }
789 else {
790 leadRow = -1;
791 }
792 insureRowContinuity();
793
794 }
795 else
796 leadRow = -1;
797 }
798
799
800
801
802
803 public int getLeadSelectionRow() {
804 return leadRow;
805 }
806
807
808
809
810
811 public TreePath getLeadSelectionPath() {
812 return leadPath;
813 }
814
815
816
817
818
819
820
821
822
823
824 public synchronized void addPropertyChangeListener(
825 PropertyChangeListener listener) {
826 if (changeSupport == null) {
827 changeSupport = new SwingPropertyChangeSupport(this);
828 }
829 changeSupport.addPropertyChangeListener(listener);
830 }
831
832
833
834
835
836
837
838
839
840 public synchronized void removePropertyChangeListener(
841 PropertyChangeListener listener) {
842 if (changeSupport == null) {
843 return;
844 }
845 changeSupport.removePropertyChangeListener(listener);
846 }
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861 public PropertyChangeListener[] getPropertyChangeListeners() {
862 if (changeSupport == null) {
863 return new PropertyChangeListener[0];
864 }
865 return changeSupport.getPropertyChangeListeners();
866 }
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882 protected void insureRowContinuity() {
883 if(selectionMode == TreeSelectionModel.CONTIGUOUS_TREE_SELECTION &&
884 selection != null && rowMapper != null) {
885 DefaultListSelectionModel lModel = listSelectionModel;
886 int min = lModel.getMinSelectionIndex();
887
888 if(min != -1) {
889 for(int counter = min,
890 maxCounter = lModel.getMaxSelectionIndex();
891 counter <= maxCounter; counter++) {
892 if(!lModel.isSelectedIndex(counter)) {
893 if(counter == min) {
894 clearSelection();
895 }
896 else {
897 TreePath[] newSel = new TreePath[counter - min];
898 int selectionIndex[] = rowMapper.getRowsForPaths(selection);
899
900
901 for (int i = 0; i < selectionIndex.length; i++) {
902 if (selectionIndex[i]<counter) {
903 newSel[selectionIndex[i]-min] = selection[i];
904 }
905 }
906 setSelectionPaths(newSel);
907 break;
908 }
909 }
910 }
911 }
912 }
913 else if(selectionMode == TreeSelectionModel.SINGLE_TREE_SELECTION &&
914 selection != null && selection.length > 1) {
915 setSelectionPath(selection[0]);
916 }
917 }
918
919
920
921
922
923 protected boolean arePathsContiguous(TreePath[] paths) {
924 if(rowMapper == null || paths.length < 2)
925 return true;
926 else {
927 BitSet bitSet = new BitSet(32);
928 int anIndex, counter, min;
929 int pathCount = paths.length;
930 int validCount = 0;
931 TreePath[] tempPath = new TreePath[1];
932
933 tempPath[0] = paths[0];
934 min = rowMapper.getRowsForPaths(tempPath)[0];
935 for(counter = 0; counter < pathCount; counter++) {
936 if(paths[counter] != null) {
937 tempPath[0] = paths[counter];
938 int[] rows = rowMapper.getRowsForPaths(tempPath);
939 if (rows == null) {
940 return false;
941 }
942 anIndex = rows[0];
943 if(anIndex == -1 || anIndex < (min - pathCount) ||
944 anIndex > (min + pathCount))
945 return false;
946 if(anIndex < min)
947 min = anIndex;
948 if(!bitSet.get(anIndex)) {
949 bitSet.set(anIndex);
950 validCount++;
951 }
952 }
953 }
954 int maxCounter = validCount + min;
955
956 for(counter = min; counter < maxCounter; counter++)
957 if(!bitSet.get(counter))
958 return false;
959 }
960 return true;
961 }
962
963
964
965
966
967
968
969
970
971 protected boolean canPathsBeAdded(TreePath[] paths) {
972 if(paths == null || paths.length == 0 || rowMapper == null ||
973 selection == null || selectionMode ==
974 TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION)
975 return true;
976 else {
977 BitSet bitSet = new BitSet();
978 DefaultListSelectionModel lModel = listSelectionModel;
979 int anIndex;
980 int counter;
981 int min = lModel.getMinSelectionIndex();
982 int max = lModel.getMaxSelectionIndex();
983 TreePath[] tempPath = new TreePath[1];
984
985 if(min != -1) {
986 for(counter = min; counter <= max; counter++) {
987 if(lModel.isSelectedIndex(counter))
988 bitSet.set(counter);
989 }
990 }
991 else {
992 tempPath[0] = paths[0];
993 min = max = rowMapper.getRowsForPaths(tempPath)[0];
994 }
995 for(counter = paths.length - 1; counter >= 0; counter--) {
996 if(paths[counter] != null) {
997 tempPath[0] = paths[counter];
998 int[] rows = rowMapper.getRowsForPaths(tempPath);
999 if (rows == null) {
1000 return false;
1001 }
1002 anIndex = rows[0];
1003 min = Math.min(anIndex, min);
1004 max = Math.max(anIndex, max);
1005 if(anIndex == -1)
1006 return false;
1007 bitSet.set(anIndex);
1008 }
1009 }
1010 for(counter = min; counter <= max; counter++)
1011 if(!bitSet.get(counter))
1012 return false;
1013 }
1014 return true;
1015 }
1016
1017
1018
1019
1020
1021
1022 protected boolean canPathsBeRemoved(TreePath[] paths) {
1023 if(rowMapper == null || selection == null ||
1024 selectionMode == TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION)
1025 return true;
1026 else {
1027 BitSet bitSet = new BitSet();
1028 int counter;
1029 int pathCount = paths.length;
1030 int anIndex;
1031 int min = -1;
1032 int validCount = 0;
1033 TreePath[] tempPath = new TreePath[1];
1034 int[] rows;
1035
1036
1037 lastPaths.clear();
1038 for (counter = 0; counter < pathCount; counter++) {
1039 if (paths[counter] != null) {
1040 lastPaths.put(paths[counter], Boolean.TRUE);
1041 }
1042 }
1043 for(counter = selection.length - 1; counter >= 0; counter--) {
1044 if(lastPaths.get(selection[counter]) == null) {
1045 tempPath[0] = selection[counter];
1046 rows = rowMapper.getRowsForPaths(tempPath);
1047 if(rows != null && rows[0] != -1 && !bitSet.get(rows[0])) {
1048 validCount++;
1049 if(min == -1)
1050 min = rows[0];
1051 else
1052 min = Math.min(min, rows[0]);
1053 bitSet.set(rows[0]);
1054 }
1055 }
1056 }
1057 lastPaths.clear();
1058
1059 if(validCount > 1) {
1060 for(counter = min + validCount - 1; counter >= min;
1061 counter--)
1062 if(!bitSet.get(counter))
1063 return false;
1064 }
1065 }
1066 return true;
1067 }
1068
1069
1070
1071
1072
1073
1074
1075 @Deprecated
1076 protected void notifyPathChange(Vector changedPaths,
1077 TreePath oldLeadSelection) {
1078 int cPathCount = changedPaths.size();
1079 boolean[] newness = new boolean[cPathCount];
1080 TreePath[] paths = new TreePath[cPathCount];
1081 PathPlaceHolder placeholder;
1082
1083 for(int counter = 0; counter < cPathCount; counter++) {
1084 placeholder = (PathPlaceHolder) changedPaths.elementAt(counter);
1085 newness[counter] = placeholder.isNew;
1086 paths[counter] = placeholder.path;
1087 }
1088
1089 TreeSelectionEvent event = new TreeSelectionEvent
1090 (this, paths, newness, oldLeadSelection, leadPath);
1091
1092 fireValueChanged(event);
1093 }
1094
1095
1096
1097
1098 protected void updateLeadIndex() {
1099 if(leadPath != null) {
1100 if(selection == null) {
1101 leadPath = null;
1102 leadIndex = leadRow = -1;
1103 }
1104 else {
1105 leadRow = leadIndex = -1;
1106 for(int counter = selection.length - 1; counter >= 0;
1107 counter--) {
1108
1109
1110 if(selection[counter] == leadPath) {
1111 leadIndex = counter;
1112 break;
1113 }
1114 }
1115 }
1116 }
1117 else {
1118 leadIndex = -1;
1119 }
1120 }
1121
1122
1123
1124
1125
1126
1127 protected void insureUniqueness() {
1128 }
1129
1130
1131
1132
1133
1134
1135
1136
1137 public String toString() {
1138 int selCount = getSelectionCount();
1139 StringBuffer retBuffer = new StringBuffer();
1140 int[] rows;
1141
1142 if(rowMapper != null)
1143 rows = rowMapper.getRowsForPaths(selection);
1144 else
1145 rows = null;
1146 retBuffer.append(getClass().getName() + " " + hashCode() + " [ ");
1147 for(int counter = 0; counter < selCount; counter++) {
1148 if(rows != null)
1149 retBuffer.append(selection[counter].toString() + "@" +
1150 Integer.toString(rows[counter])+ " ");
1151 else
1152 retBuffer.append(selection[counter].toString() + " ");
1153 }
1154 retBuffer.append("]");
1155 return retBuffer.toString();
1156 }
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166 public Object clone() throws CloneNotSupportedException {
1167 DefaultTreeSelectionModel clone = (DefaultTreeSelectionModel)
1168 super.clone();
1169
1170 clone.changeSupport = null;
1171 if(selection != null) {
1172 int selLength = selection.length;
1173
1174 clone.selection = new TreePath[selLength];
1175 System.arraycopy(selection, 0, clone.selection, 0, selLength);
1176 }
1177 clone.listenerList = new EventListenerList();
1178 clone.listSelectionModel = (DefaultListSelectionModel)
1179 listSelectionModel.clone();
1180 clone.uniquePaths = new Hashtable<TreePath, Boolean>();
1181 clone.lastPaths = new Hashtable<TreePath, Boolean>();
1182 clone.tempPaths = new TreePath[1];
1183 return clone;
1184 }
1185
1186
1187 private void writeObject(ObjectOutputStream s) throws IOException {
1188 Object[] tValues;
1189
1190 s.defaultWriteObject();
1191
1192 if(rowMapper != null && rowMapper instanceof Serializable) {
1193 tValues = new Object[2];
1194 tValues[0] = "rowMapper";
1195 tValues[1] = rowMapper;
1196 }
1197 else
1198 tValues = new Object[0];
1199 s.writeObject(tValues);
1200 }
1201
1202
1203 private void readObject(ObjectInputStream s)
1204 throws IOException, ClassNotFoundException {
1205 Object[] tValues;
1206
1207 s.defaultReadObject();
1208
1209 tValues = (Object[])s.readObject();
1210
1211 if(tValues.length > 0 && tValues[0].equals("rowMapper"))
1212 rowMapper = (RowMapper)tValues[1];
1213 }
1214 }
1215
1216
1217
1218
1219 class PathPlaceHolder {
1220 protected boolean isNew;
1221 protected TreePath path;
1222
1223 PathPlaceHolder(TreePath path, boolean isNew) {
1224 this.path = path;
1225 this.isNew = isNew;
1226 }
1227 }